<script lang="ts">
    import { onDestroy, onMount } from "svelte";
    import type { ColumnProps, TableStore } from "./Table";
    import Colgroup from "./Colgroup.svelte";
    import Cell from "./Cell.svelte";

    export interface SummaryProps {
        data: TableStore;
        summaryMethod?: (columns: ColumnProps[], data: any[]) => any;
        onResizeSummary: (width: number, height: number) => void;
    }

    const props: SummaryProps = $props();

    let summary: any;

    const summaryData = $derived.by(() => {
        let row: any = {};
        if (props.summaryMethod) {
            row = props.summaryMethod(props.data.columns, props.data.data);
        } else {
            props.data.columns.forEach((col: ColumnProps, index: number) => {
                const key = col.name!;
                if (index === 0) {
                    row[key] = "合计";
                    return;
                }
                const values = props.data.data.map((item) => Number(item[key]));
                if (!values.every((value) => isNaN(value))) {
                    const v = values.reduce((prev, curr) => {
                        const value = Number(curr);
                        if (!isNaN(value)) {
                            return prev + curr;
                        } else {
                            return prev;
                        }
                    }, 0);
                    row[key] = v;
                } else {
                    row[key] = "";
                }
            });
        }
        return row;
    });

    $effect(() => {
        if (summary) {
            summary.scrollLeft = props.data.headerLeft;
        }
    });

    const onEntryResize = (entry: ResizeObserverEntry) => {
        const el = entry.target;
        if (el.classList.contains("cm-table-summary")) {
            const rect = el.getBoundingClientRect();
            const tableH = el.children[0].getBoundingClientRect().height;

            props.onResizeSummary(rect.width, tableH);
            summary.style.height = tableH + "px";
        } else {
            // setTimeout, header变化让body设置height后再计算是否有垂直滚动条
            setTimeout(() => {
                const rect = el.getBoundingClientRect();
                const parentRect = el.closest(".cm-table-body")!.getBoundingClientRect();

                if (rect.height > parentRect.height) {
                    summary.style.overflowY = "scroll";
                } else {
                    summary.style.overflowY = "";
                }
            });
        }
    };

    onMount(() => {
        const ro = new ResizeObserver((entries) => {
            entries.forEach((entry) => onEntryResize(entry));
        });
        ro.observe(summary);
        const parent = summary.closest(".cm-table");
        const body = parent.querySelector(".cm-table-body-wrap");
        ro.observe(body);
        onDestroy(() => {
            ro.unobserve(summary);
            ro.unobserve(body);
        });
    });
</script>

<div class="cm-table-summary" bind:this={summary}>
    <table>
        <Colgroup data={props.data} />
        <thead style="display: none">
            <tr>
                {#each props.data.columns as col, index (col.name || col.type)}
                    <Cell column={col} type="th" placeholder colIndex={index} checkedAll={props.data.checkedAll} />
                {/each}
            </tr>
        </thead>
        <tbody>
            <tr>
                {#each props.data.columns as col, index (col.name || col.type)}
                    <Cell type="td" summary data={summaryData} column={col} colIndex={index} {index} showFixedLeft={props.data.showFixedLeft} showFixedRight={props.data.showFixedRight} />
                {/each}
            </tr>
        </tbody>
    </table>
</div>
